package com.anxin.act.listener;

import com.anxin.act.task.entity.WfActHiComment;
import com.anxin.act.task.entity.WfActRuTask;
import com.anxin.act.task.service.WfActRuTaskService;
import com.anxin.act.utils.ActCommentUtils;
import com.anxin.act.utils.ActUtils;
import com.anxin.common.utils.StringUtils;
import com.anxin.common.utils.sys.UserUtils;
import com.anxin.sys.system.entity.SysRole;
import com.anxin.sys.system.entity.SysUser;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.CommentEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.task.Comment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Configuration
public class signListener implements ExecutionListener,TaskListener {

	private Logger logger = LoggerFactory.getLogger("sys-info");
	private static final long serialVersionUID = 1L;
	@Autowired
	private HistoryService historyService;

	@Autowired
	private RuntimeService runtimeService;
	@Autowired
	private WfActRuTaskService wfActRuTaskService;

	@Override
	public void notify(DelegateTask delegateTask) {

	}

	@Override
	public void notify(DelegateExecution execution) throws Exception {

	}

	/**
	 * 会签带一条否决权
	 * @param execution
	 * @param opinion
	 * @param percentage
	 * @param role
	 * @return
	 */
	public boolean sign(DelegateExecution execution,String opinion,Double percentage,String role){
		return this.signTwo(execution,opinion,null,percentage,role);
	}


	/**
	 * 会签带一条否决权
	 * @param execution
	 * @param opinion
	 * @param percentage
	 * @param role
	 * @return
	 */
	public boolean signTwo(DelegateExecution execution,String opinion,String opinion2,Double percentage,String role){
		List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().processInstanceId(execution.getProcessInstanceId()).orderByTaskCreateTime().asc().list();

		double tynum= 0;
		double num=0;

		HistoricTaskInstance historicTaskInstance = list.get(list.size() - 1);
		Execution taskExecution = runtimeService.createExecutionQuery().executionId(historicTaskInstance.getExecutionId()).singleResult();

		for (HistoricTaskInstance histTask : list) {
			//boolean timeJudge = startTime.getTime() == histIns.getStartTime().getTime() || (startTime.getTime() - histIns.getStartTime().getTime() <5000) || (histIns.getStartTime().getTime() - startTime.getTime()  > -5000);

			Execution execution1 = runtimeService.createExecutionQuery().executionId(histTask.getExecutionId()).singleResult();

			if(execution1 != null && execution1.getParentId() != null && taskExecution != null && taskExecution.getParentId() != null){
				if (taskExecution.getParentId().equals(execution1.getParentId())) {
					num++;
					if (!"-2".equals(histTask.getAssignee())){
						List<WfActHiComment> commentList = ActCommentUtils.getCommentList(histTask);
						for (WfActHiComment comment : commentList) {
							if ((comment.getMessage().indexOf(opinion)==0) || (StringUtils.isNotBlank(opinion2) && comment.getMessage().indexOf(opinion2)==0)) {

								//是否有一票决策权
								if (StringUtils.isNotBlank(role)) {
									SysUser user = UserUtils.getUserByUserName(histTask.getAssignee());
									for (SysRole userRole : user.getRoles()) {
										if (role.equals(userRole.getRoleKey())) {
											return true;
										}
									}
								}

								tynum++;
							}
						}
					}
				}
			}

		}
		logger.info("同意人数："+tynum+",投票人数："+num+"");
		if (tynum==0 || num==0) {
			return false;
		}else if (tynum/num > percentage) {
			return true;
		}

		return false;
	}

	/**
	 * 5
	 * 例子：${signListener.sign(execution,'审批结果:同意',0.99) || signListener.sign(execution,'审批结果:不同意',0.0000001)}
	 * 会签不带一条否决权
	 * @param execution
	 * @param opinion
	 * @param percentage
	 * @return
	 */
	public boolean signTwo(DelegateExecution execution,String opinion,String opinion2,Double percentage){
		return signTwo(execution,opinion,opinion2,percentage,"");
	}

	/**
	 * 5
	 * 例子：${signListener.sign(execution,'审批结果:同意',0.99) || signListener.sign(execution,'审批结果:不同意',0.0000001)}
	 * 会签不带一条否决权
	 * @param execution
	 * @param opinion
	 * @param percentage
	 * @return
	 */
	public boolean sign(DelegateExecution execution,String opinion,Double percentage){
		return signTwo(execution,opinion,null,percentage,"");
	}

	/**
	 * 用户配置完成条件，如果达到完成条件也会自动完成所有加签任务
	 * @param execution
	 * @param opinion
	 * @param percentage
	 * @return
	 */
	public boolean completion(DelegateExecution execution,String opinion,Double percentage){
		boolean res = signTwo(execution, opinion, null, percentage, "");
		if (res){
			List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().processInstanceId(execution.getProcessInstanceId()).orderByTaskCreateTime().asc().list();
			HistoricTaskInstance historicTaskInstance = list.get(list.size() - 1);
			Execution taskExecution = runtimeService.createExecutionQuery().executionId(historicTaskInstance.getExecutionId()).singleResult();

			for (HistoricTaskInstance histTask : list) {

				Execution execution1 = runtimeService.createExecutionQuery().executionId(histTask.getExecutionId()).singleResult();

				if(execution1 != null && execution1.getParentId() != null && taskExecution != null && taskExecution.getParentId() != null){
					if (taskExecution.getParentId().equals(execution1.getParentId())) {
						if ("-2".equals(histTask.getAssignee())){
							List<WfActRuTask> wfActRuTaskList = wfActRuTaskService.findByActTaskId(histTask.getId());
							for (WfActRuTask wfActRuTask : wfActRuTaskList) {
								wfActRuTaskService.complete(wfActRuTask.getId(),new HashMap<>());
							}
						}
					}
				}

			}
		}

		return res;
	}
}
